//=============================================================================

#include "tinyxml.h"
/////////////////////////////////////////////
#include "common.hpp"
#include "log.hpp"
#include "filemanager.hpp"
#include "global.hpp"
/////////////////////////////////////////////
#include "frames.hpp"
#include "texture.hpp"

namespace KEG
{
	inline void ComputeTexCoord( TileTexture& tileTex, int moreTiles, int maxCoord, float startx, float starty,
									float jumpx, float jumpy, float tileTexWidth, float tileTexHeight )
	{
		// Loop through the number of tiles
		float left, top, right, bottom;
		left = startx;
		top = starty;
		right = startx + tileTexWidth;
		bottom = starty + tileTexHeight;

		for(int i=0; i<moreTiles; ++i)
		{
			tileTex.Coord.push_back( left );
			tileTex.Coord.push_back( top );
			tileTex.Coord.push_back( right );
			tileTex.Coord.push_back( bottom );

			// increment left
			left += jumpx;
			// check if too far
			if( left + jumpx > maxCoord )
			{
				left = startx;
				top += jumpy;
			}

			// compute next iteration
			right = left + tileTexWidth;
			bottom = top + tileTexHeight;
		}
	}

	bool LoadTilesAndTex( const std::string& filename, TileTexture& tileTex,
		Texture& texInfo )
	{
		LOG_RAW() << "Loading Tiles and Texture from: " << filename << std::endl;
		
		TiXmlDocument *xmlDoc = new TiXmlDocument(filename);
		if (!xmlDoc->LoadFile())
		{
			// Fatal error, cannot load
			LOG_ERROR( "Frame file not found (follows)" );
			LOG_RAW() << filename << std::endl;
			return 0;
		}

		// Grab the outer element
		TiXmlElement *framesNode = xmlDoc->FirstChildElement("frames");
		if( !framesNode )
		{
			LOG_ERROR( "Frames XML broken" );
			return 0;
		}

		// Load the texture
		const char* imageName = framesNode->Attribute("image");
		int filter = 0;
		framesNode->QueryIntAttribute("filter",&filter);
		if( false ==
			texInfo.Load( Path( IMAGE, imageName ) ) )
		{
			LOG_ERROR( "Failed to read texture" );
			//LOG_RAW() << framesNode->Attribute("image") << std::endl;
		}

		// Grab all tile frames
		TiXmlElement *tileNode = framesNode->FirstChildElement("tiles");
		if( !tileNode )
		{
			LOG_ERROR( "No tile data found when loading tiles" );
			return 0;
		}
		
		// set number=0 to count up
		//number = 0;
		while( tileNode )
		{
			//std::stringstream sstr;
			int moreTiles = 0;
			int tilewidth=16, tileheight=16, padding=1, xpos=0, ypos=0;
			
			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "width", &tilewidth ) )
			{
				LOG_ERROR( "Invalid Width Param" );
			}

			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "height", &tileheight ) )
			{
				LOG_ERROR( "Invalid Height Param" );
			}

			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "padding", &padding ) )
			{
				LOG_ERROR( "Invalid Padding Param" );
			}

			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "number", &moreTiles ) )
			{
				LOG_ERROR( "Invalid Number Param" );
			}
			//else
			//{
			//	number += moreTiles;
			//}
			
			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "x", &xpos ) )
			{
				LOG_ERROR( "Invalid X Start Position" );
			}

			// check if XXXX failed?
			if( TIXML_SUCCESS != tileNode->QueryIntAttribute( "y", &ypos ) )
			{
				LOG_ERROR( "Invalid Y Start Position" );
			}

			// Check if using denormalized coordinates and call appropriate function
			// to load texture coordinates

			// Calculate the starting texcoords
			float startx = float(xpos+padding);
			float starty = float(ypos+padding);
			// Calc each jump
			float jumpx = float(tilewidth+padding);
			float jumpy = float(tileheight+padding);
			// Calc each tile width in texcoords
			float tileTexWidth = float(tilewidth);
			float tileTexHeight = float(tileheight);
			//
			int maxCoord = texInfo.Width;

#ifdef PATHWAY
			if( !Global::OGLCaps::TexRect || Global::OGLCaps::NonPow2 )
			{
				startx /= texInfo.width;
				starty /= texInfo.height;
				jumpx /= texInfo.width;
				jumpy /= texInfo.height;
				tileTexWidth /= texInfo.width;
				tileTexHeight /= texInfo.height;

				maxCoord = 1.0;
			}
#endif

			tileTex.Padding = padding;
			tileTex.TileHeight = tileheight;
			tileTex.TileWidth = tilewidth;
			tileTex.Height = texInfo.Height/tileheight;
			tileTex.Width = texInfo.Width/tilewidth;

			ComputeTexCoord( tileTex, moreTiles, maxCoord,
				startx, starty, jumpx, jumpy, tileTexWidth, tileTexHeight );

			// get the next tileNode
			tileNode = tileNode->NextSiblingElement("tiles");
			
		}

		xmlDoc->Clear();
		delete xmlDoc;
		return 1;
	}

}
